#version 400 core
layout(quads, fractional_even_spacing, cw) in;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;

out TES_OUT
{
   vec3 N;
}tes_out;

vec4 quad_bezier(vec4 A, vec4 B, vec4 C, float t)
{
    vec4 D = mix(A, B, t);
    vec4 E = mix(B, C, t);
    return mix(D, E, t);
}

vec4 cube_bezier(vec4 A, vec4 B, vec4 C, vec4 D, float t)
{
    vec4 E = mix(A, B, t);
    vec4 F = mix(B, C, t);
    vec4 G = mix(C, D, t);
    return quad_bezier(E, F, G, t);
}

vec4 evaluate_patch(vec2 at)
{
    vec4 P[4];
    int i;
    for(i = 0; i < 4; i++)
    {
        P[i] = cube_bezier(gl_in[i + 0].gl_Position, gl_in[i + 4].gl_Position,
                       gl_in[i + 8].gl_Position, gl_in[i + 12].gl_Position, at.y);
    }
    return cube_bezier(P[0], P[1], P[2], P[3], at.x);
}

const float epsilon = 0.001;

void main()
{
    vec4 p1 = evaluate_patch(gl_TessCoord.xy);
    vec4 p2 = evaluate_patch(gl_TessCoord.xy + vec2(0.0, epsilon));
    vec4 p3 = evaluate_patch(gl_TessCoord.xy + vec2(epsilon, 0.0));

    vec3 v1 = normalize(p2.xyz - p1.xyz);
    vec3 v2 = normalize(p3.xyz - p1.xyz);

    tes_out.N = cross(v1, v2);
    gl_Position = proj_matrix * p1;
}




